/**
 * Copyright 2011-2011 - Members of the Chaupal Community
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package net.chaupal.Impl.v1.Proof.ConfirmationProtocol;

/**
 * Tool class to generate all combinations of event in the Chaupal confirmation 
 * protocols.
 */
public class CPSequence {

    private CPEvent[] eventSequence;

    private final String shortCode;

    /**
     * Defines a sequences of events initiated by Alice.
     *
     * @param events set of events for the sequence
     */
    public CPSequence(CPEvent... events) {

        eventSequence = events.clone();
        String tmp = "";

        if ( events != null ) {
            for (int i=0;i<events.length;i++) {
                tmp += events[i].getShortCode();
            }
        }

        shortCode = tmp;

    }

    /**
     * Copy constructor
     *
     * @param copy the sequence to copy
     */
    @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
    public CPSequence(CPSequence copy) {
        eventSequence = copy.eventSequence;
        shortCode = copy.shortCode;
    }

    public CPSequence(String sc) {
        eventSequence = null;
        shortCode = sc;
    }

    @Override
    @SuppressWarnings("AccessingNonPublicFieldOfAnotherObject")
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CPSequence other = (CPSequence) obj;
        if ((this.shortCode == null) ? (other.shortCode != null) : !this.shortCode.equals(other.shortCode)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 97 * hash + (this.shortCode != null ? this.shortCode.hashCode() : 0);
        return hash;
    }

    public final String getShortCode() {
        return shortCode;
    }

    public final CPEvent[] getSequence() {
        return eventSequence.clone();
    }

    @Override
    public String toString() {
        return shortCode;
    }

    public String toLongString() {

        // Preparing result
        StringBuilder result = new StringBuilder();

        for (int i=0;i<eventSequence.length;i++) {
            result.append(i+1);
            if ( eventSequence[i].getMessageType().equals(
                    CPMessageType.WELL_RECEIVED) ) {
                result.append(" B <- ");
            } else {
                result.append(" A -> ");
            }
            result.append(eventSequence[i].getMessageType().toString());
            result.append(" - ");
            result.append(eventSequence[i].getMessageArrivalTiming().toString());
            result.append("\n");
        }

        // Returning result
        return result.toString();

    }

}
